package main

import "fmt"

// https://refactoringguru.cn/design-patterns/observer

const (
	EventTypeInput  = 1
	EventTypeOutput = 2
)

type Subscriber interface {
	Update(e string)
}

type Publisher struct {
	msubs map[int][]Subscriber
}

func NewPublisher() *Publisher {
	return &Publisher{msubs: make(map[int][]Subscriber)}
}

func (p *Publisher) Pub(e int, event string) {
	subs, ok := p.msubs[e]
	if !ok {
		return
	}
	for i := range subs {
		subs[i].Update(event)
	}
}

func (p *Publisher) Sub(e int, sub Subscriber) {
	subs, ok := p.msubs[e]
	if !ok {
		subs = make([]Subscriber, 0)
	}
	subs = append(subs, sub)
	p.msubs[e] = subs
}

//////////

type Inputer struct{}

func (Inputer) Update(event string) {
	fmt.Println("inputer receive event:", event)
}

type Outputer struct{}

func (Outputer) Update(event string) {
	fmt.Println("outputer receive event:", event)
}

func main() {
	p := NewPublisher()
	p.Sub(EventTypeInput, &Inputer{})
	p.Sub(EventTypeOutput, &Outputer{})
	p.Pub(EventTypeInput, "input message")
	p.Pub(EventTypeOutput, "output message")
}
